
/**
 * @version			$Id$
 * @create 			2012-8-30 16:04:14 By xjiujiu
 * @package 		is
 * @copyRight 		Copyright (c) 2011-2012 http://www.xjiujiu.com.All right reserved
 * HongJuZi Framework
 */

 /**
  * HHJsLib的验证基础库 
  * 
  * 常用的空值检测，长度判断，邮箱验证等 
  * 
  * @author xjiujiu <xjiujiu@foxmail.com>
  * @package is
  * @since 1.0.0
  */
 (function($) {
	 var HHValidate     = {
        //attributes
    	domId: null, 	//当前正在检测的DOM ID标识
    	value: null, 	//当前正在检测的值
    	name: null, 	//当前正在检测的内容名称
    	
        /**
         * 验证当前对象是否为空 
         * 
         * 包括对空对象，空对象的检测 
         * 
         * @author 			xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  Object target 需要检测的对象
         * @param  String name 当前对象的名称
         * @param  mix def 默认值
         * @return boolean
         * @throws HHValidateException
         */
        isEmpty: function(target, name, def) {
        	try {
        		if(typeof target == 'undefined' || target == '') {
		            throw name + HHJsLib.lang('CAN_NOT_EMPTY');
	            }
	            if(arguments.length == 3 && target == def) {
		            throw name + HHJsLib.lang('CAN_NOT_EMPTY');
	            }
	            return arguments.length == 1 ? false : this;
        	} catch(e) {
	        	if(arguments.length == 1) {
		        	return true;
	        	}
        		throw e;
        	}
        },

        /**
         * 查看DOM元素的值是否为空
         * 
         * 用法：
         * <code>
         *      HHJsLib.isEmptyByDomId('domId', '名称', '我是默认的');
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String domId 需要检测的domId
         * @param  String name 当前的dom的元素名称
         * @param  mix def 里面的默认值
         * @return void
         * @throws HHValidateException 
         */
        isEmptyByDomId: function(domId, name, def) {
            try {
                return this.isEmpty($('#' + domId).val(), name, def);
            } catch(e) {
                throw {info: e, id: domId };
            }
        },
        
        /**
         * 验证字符串长度 
         * 
         * 对当前串进行长度验证 ,用法：
         * <code>
         *    HHJsLib.isStrLen("xjiujiu", "用户名", 1, 20); //ok
         *    HHJsLib.isStrLen("", "用户名", 1, 20); //HHValidateException
         * </code>
         * 
         * @author 			xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String target 需要验证的字串
         * @param  String name 当前字串的名称
         * @param  int min 最少长度
         * @param  int max 最大长度
         * @return void
         * @throws HHValidateException
         */
        isStrLen: function(target, name, min, max) {
            if(target.length < min || max < target.length) {
                throw name + HHJsLib.lang('LEN_INAVALIBLE') + min + '~' + max + "。";
            }
            
            return this;
        },

        /**
         * 通过文档元素的ID来验证当前值的长度是否合法 
         * 
         * 用法：
         * <code>
         *      HHJsLib.isStrLenByDomId("domId", "名称", 2, 10);
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String domId 文档元素的ID属性值
         * @param  String name 当前元素的名称
         * @param  int min 最少值
         * @param  int max 最大值
         * @return void
         * @throws HHValidateException 
         */
        isStrLenByDomId: function(domId, name, min, max) {
            try {
                return this.isStrLen($('#' + domId).val(), name, min, max);
            } catch(e) {
                throw { info: e, id: domId };
            }
        },

        /**
         * 验证当前的邮箱地址是否合法 
         * 
         * 对已知的邮箱地址进行合法性验证，用法如：
         * <code>
         *   HHJsLib.isEmail("xjiujiu@foxmai.com"); //ok
         *   HHJsLib.isEmail("aa@aaa"); //HHValidateException
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String target 需要验证的目标邮箱地址
         * @return void
         * @throws HHValidateException 
         */
        isEmail: function(target) {
            var emailRegExp     = /^(?:[a-zA-Z0-9]+[_\-\+\.]?)*[a-zA-Z0-9]+@(?:([a-zA-Z0-9]+[_\-]?)*[a-zA-Z0-9]+\.)+([a-zA-Z]{2,})+$/i; 
            if(!emailRegExp.test(target)) {
                throw HHJsLib.lang('EMAIL_FORMAT_ERROR');
            }
            
            return this;
        },

        /**
         * 通过文档的ID来验证邮箱值是否合法 
         * 
         * 用法：
         * <code>
         *      HHJsLib.isEmailByDomId('email_id'); 
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String domId 当前的元素ID
         * @return void
         * @throws HHValidateException
         */
        isEmailByDomId: function(domId) {
            try {
                return this.isEmail($('#' + domId).val());
            } catch(e) {
                throw { info: e, id: domId };
            }
        },

        /**
         * 验证电话号码是否合法 
         * 
         * 用法：
         * <code>
         *      HHJsLib.isPhone('127123132'); //throw HHValidateException
         *      HHJsLib.isPhone('0745-2658963');  //正确 no HHValidateException
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String target 电话值
         * @return void
         * @throws HHValidateException
         */
        isPhone: function(target) {
            var phoneRegExp     = /^1[35]?\d{5,9}$/; 
            var telRegExp       = /^(([0+]\d{2,3}-)?(0\d{2,3})-)?(\d{7,8})(-(\d{3,}))?$/;
            if(!phoneRegExp.test(target) && !telRegExp.test(target)) {
                throw HHJsLib.lang('PHONE_ERROR');
            }
            
            return this;
        },

        /**
         * 通过当前DOM ID来验证值是否为正确的电话号码 
         * 
         * 用法：
         * <code>
         *      HHJsLib.isPhoneByDomId('phone_id');
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String domId 当前的DOM ID值
         * @return void
         * @throws HHValidateException 
         */
        isPhoneByDomId: function(domId) {
            try {
                return this.isPhone($('#' + domId).val());
            } catch(e) {
                throw { info: e, id: domId };
            }
        },
        
        /**
         * 验证值是否全为数字 
         * 
         * 用法：
         * <code>
         *      HHJsLib.isNumber(121323);   //Yes..
         *      HHJsLib.isNumber('est');   //异常抛出
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String domId 当前的DOM ID值
         * @param  String name 当前检测的元素名称
         * @return HHJsLib 
         * @throws HHValidateException 
         */
        isNumber: function (num, name) {
            if(!/^\d+.?\d*$/.test(num)) {
                throw name + HHJsLib.lang('INAVALIBLE_NUMBER');
            }
            
            return this;
        },

        
        /**
         * 通过当前DOM ID来验证值是否全为数字
         * 
         * 用法：
         * <code>
         *      HHJsLib.isNumberByDomId('phone_id');
         * </code>
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String domId 当前的DOM ID值
         * @return void
         * @throws HHValidateException 
         */
        isNumberByDomId: function(domId, name) {
            try {
                return this.isNumber($('#' + domId).val(), name);
            } catch(e) {
                throw {info: e, id: domId };
            }
        },
        
        
		
		/**
         
		 * 是否为IE浏览器 
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isIE();
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @return boolean 是否为IE浏览器
         
		 */
        isIE: function() {
        	return !-[1,];
        },
       
        /**
         
		 * 是否支持当前的文件类型 
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isFileType("#file-id", ".jpg,.gif");
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @throws HHVerifyException 是否验证成功
         */
        isFileType: function(domId, types) {
        	var path 			= $("#" + domId).val();
        	var regFileType 	= "," + types + ",";
        	var fileType 		= "," + path.substring(path.lastIndexOf('.')) + ",";
        	if(-1 == regFileType.indexOf(fileType)) {
        		throw {info: HHJsLib.lang('NOT_SUPPORT_THE_FILE_TYPE'), id: domId };
        	}
        	
        	return this;
        },
        
        /**
         
		 * 是否支持当前所要求的日期格式
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isDateByDomId("#date-id", "出生年月", "yyyy-mm");
         
		 * </code>
         * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @param  String domId 需要检测的DOM ID值
         * @param  String name 当前的检测项目名称
         * @param  String format 功能所支持的日期格式
         * @throws HHVerifyException 是否验证成功
         */
        isDateByDomId: function(domId, name, format) {
        	try {
        		return this.isDate($("#" + domId).val(), name, format);
        	} catch(e) {
        		throw {"info": e, "id": domId};
        	}
        },
        
        /**
         
		 * 是否支持当前所要求的日期格式
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isDate("200304", "出生年月", "yyyy-mm");
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @param  String value 需要检测的值
         * @param  String name 当前的检测项目名称
         * @param  String format 功能所支持的日期格式
         * @throws HHVerifyException 是否验证成功
         */
        isDate: function(value, name, format) {
        	var dateFormatMap 	= {
        		"yyyy/mm/dd": /^\d{4}\/\d{2}\/\d{2}$/,
        		"yyyy/mm": /^\d{4}\/\d{2}$/,
        		"yyyy-mm-dd": /^\d{4}-\d{2}-\d{2}$/,
        		"yyyy-mm": /^\d{4}-\d{2}$/,
        		"yyyymmdd": /^\d{8}$/,
        		"yyyymm": /^\d{4}$/
        	};
        	if(typeof format == 'undefined') {
        		format 	= 'yyyymmdd';
        	}
        	if(!dateFormatMap[format].test(value)) {
        		throw name + "时间格式不正确，请参考说明认真填写！";
        	}
    		value 		= value.replace(/-|\//g, "");
    		var year 	= parseInt(value.substr(0, 4));
    		if(year > 2037) {
        		throw name + "日期值太大，不能超过2037年！";
    		}
    		var month 	= parseInt(value.substr(4, 2));
    		if(12 < month) {
        		throw name + "日期格式无效！";
    		}
    		var day		= parseInt(value.substr(6, 2));
    		if(day > 31) {
        		throw name + "日期格式无效！";
    		}
    		if(month == 2 && day > 29) {
        		throw name + "日期格式无效！2月最大只有29天~";
    		}
    		
    		return this;
        },
        
        /**
         
		 * 身份证格式是否正确
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isIdCardByDomId("cardid_id");
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @param  String dom 需要检测的域
         * @throws HHVerifyException 是否验证成功
         */
        isIdCardByDomId: function(dom, value) {
        	try {
        		return this.isIdCard($("#" + dom).val());
        	} catch(e) {
        		throw {info: e, id: dom};
        	}
        },
        
        /**
         
		 * 身份证格式是否正确
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isIdCard("29u0u8080u09009");
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @param  String value 需要检测的值
         * @throws HHVerifyException 是否验证成功
         */
        isIdCard: function(value) {
        	if(!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(value))) {
        		throw HHJsLib.lang('CARD_ID_ERROR');
        	}
        	
        	return this;
        },
        
        /**
         
		 * 名族格式是否正确
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isNation("汉族");
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @param  String value 需要检测的值
         * @throws HHVerifyException 是否验证成功
         */ 
        isNationByDomId: function(domId) {
        	try {
        		return this.isNation($("#" + domId).val());
        	} catch(e) {
        		throw {info: e, id: domId };
        	}
        },
        
        /**
         
		 * 名族格式是否正确
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isNation("汉族");
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @param  String value 需要检测的值
         * @throws HHVerifyException 是否验证成功
         */
        isNation: function(value) {
        	var nations = ",汉族,壮族,满族,回族,苗族,维吾尔族,土家族,彝族," +
			"蒙古族,藏族,布依族,侗族,瑶族,朝鲜族,白族,哈尼族,哈萨克族," +
			"黎族,傣族,畲族,傈僳族,仡佬族,东乡族,高山族,拉祜族,水族," +
			"佤族,纳西族,羌族,土族,仫佬族,锡伯族,柯尔克孜族,达斡尔族," +
			"景颇族,毛南族,撒拉族,布朗族,塔吉克族,阿昌族,普米族,鄂温克族," +
			"怒族,京族,基诺族,德昂族,保安族,俄罗斯族,裕固族,乌兹别克族," +
			"门巴族,鄂伦春族,独龙族,塔塔尔族,赫哲族,珞巴族,";
        	
        	return this.isHasStr(nations, value, "民族");
        },
        
        /**
         
		 * 是否包含当前需要查找的字符串
         
		 * 
         
		 * Example:
         
		 * <code>
         
		 *  HHJsLib.isHasStr(",1,2,3,", 1, "数字");
         
		 * </code>
         
		 * 
         
		 * @author xjiujiu <xjiujiu@foxmail.com>
         
		 * @access public
         * @param  String str 对比的模板
         * @param  String needle 需要查找的字串
         * @param  String name 当前的内容名称
         * @param  String char 限定范围字符串 默认为：,
         * @throws HHVerifyException 是否验证成功
         */
        isHasStrByDomId: function(domId, str, name, char) {
        	try {
        		return this.isHasStr(str, $("#" + domId).val(), name, char);
        	} catch(e) {
        		throw { info: e, id: domId };
        	}
        },
        
        /**
		 * 是否包含当前需要查找的字符串
		 * 
		 * Example:
		 * <code>
		 *  HHJsLib.isHasStr(",1,2,3,", 1, "数字");
		 * </code>
		 * 
		 * @author xjiujiu <xjiujiu@foxmail.com>
		 * @access public
         * @param  String str 对比的模板
         * @param  String needle 需要查找的字串
         * @param  String name 当前的内容名称
         * @param  String char 限定范围字符串 默认为：,
         * @throws HHVerifyException 是否验证成功
         */
        isHasStr: function(str, needle, name, char) {
        	if(typeof char == 'undefined') {
        		var char 	= ',';
        	}
        	if(0 > str.indexOf(char + needle + char)) {
        		throw name + HHJsLib.lang('HAS_INVALIDATE_INFO');
        	}
        	
        	return this;
        },

        /**
         * 检测复选框是否选择
         * 
         * @desc
         * 
         * @author xjiujiu <xjiujiu@foxmail.com>
         * @access public
         * @param  String target 检测目标
         * @param  String name 对象名称
         * @throws VerifyException 验证异常 
         */
        isCheckedByDomId: function(target, name) {
            if(1 > $('#' + target + ":checked").length) {
                throw {id: target, info: name + HHJsLib.lang('NO_SELECTED') }
            }
        }
     };
     //扩展到HHJsLib库中
     HHJsLib.extend(HHValidate);
	 //添加验证的语言字典
     HHJsLib.mergeDict({
		'zh-cn': {
			'CAN_NOT_EMPTY': '不能为空！',
			'LEN_INAVALIBLE': '长度不符合要求，要求字符范围：',
			'EMAIL_FORMAT_ERROR': '邮箱地址不合法！正确格式为：example@example.com。',
			'PHONE_ERROR': '电话号码不合法！正确格式,如：13745623698 或 0745-2864032。',
			'INAVALIBLE_NUMBER': '不是有效的数字！',
			'CARD_ID_ERROR': "身份证号码格式不正确！",
			'HAS_INVALIDATE_INFO': "信息不正确，请认真核对！",
			'NOT_SUPPORT_THE_FILE_TYPE': '文件类型不支持，请参考上传说明！',
            'NO_SELECTED': '没有选择'
		},
		'zh-tw': {
			'CAN_NOT_EMPTY': '不能爲空！',
			'LEN_INAVALIBLE': '長度不符合要求，要求字符範圍：',
			'EMAIL_FORMAT_ERROR': '郵箱地址不合法！正確格式爲：example@example.com',
			'PHONE_ERROR': '電話號碼不合法！正確格式,如：13745623698 或 0745-2864032。',
			'INAVALIBLE_NUMBER': '不是有效的數字！',
			'CARD_ID_ERROR': "身份證號碼格式不正確！",
			'HAS_INVALIDATE_INFO': "信息不正確，請認真核對！",
			'NOT_SUPPORT_THE_FILE_TYPE': '文件類型不支持，請參考上傳說明！',
            'NO_SELECTED': '沒有選擇'
		},
		'en': {
			'CAN_NOT_EMPTY': 'Can not be empty!',
			'LEN_INAVALIBLE': 'length not avalible, the length should between: ',
			'EMAIL_FORMAT_ERROR': 'The phone number error, example：13745623698 or 0745-2864032.',
			'INAVALIBLE_NUMBER': 'The value is not a number!',
			'CARD_ID_ERROR': "CardId number format error!",
			'HAS_INVALIDATE_INFO': "The file type not support, please see the comments clear!",
            'NO_SELECTED': 'Not be selected!'
		}
	});
 })(jQuery);
 
